<template>
  <div class="app-container">
    <div :class="['filter-container','open']" style="height:55px!important">

      <!-- 展开状态下的筛选框 -->
      <el-form ref="form" :inline="true" :model="form" label-width="100px">
        <el-form-item label="数据库名称">
          <el-input v-model="form.dbName" clearable placeholder="" />
        </el-form-item>
        <el-form-item>
          <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
            查询
          </el-button>
          <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit-outline" @click="handleReset">
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-button class="filter-item" type="primary" style="margin-bottom: 15px;" @click="onDataSourceAdd">
      新增
    </el-button>
    <el-row :gutter="12" style="height:calc(100vh - 260px);overflow-y:scroll">
      <el-col v-for="item in list" :key="item.id" :span="6">
        <el-card shadow="always" style="cursor: pointer;margin-bottom:10px;">
          <div @click="handleLook(item)">
            <p class="oneStyle">数据库名称：{{ item.dbName }}</p>
            <p class="threeStyle" style="display: flex;justify-content: space-between;">
              <span>创建人：{{item.admin_Name}}</span>
              <span>{{item.create_Time}}</span>
            </p>
            <p class="threeStyle" style="display: flex;justify-content: space-between;">
              <span>数据库别名：{{item.dbDesc}}</span>
              <span>数据库类型：{{ item.dbTypeName }}</span>
            </p>
            <div style="text-align: right;">
              <el-button type="primary" @click.stop="handleCopy(item)">复制</el-button>
              <el-button type="primary" @click.stop="handleEdit(item)">编辑</el-button>
              <el-button type="danger" @click.stop="handleDelete(item)">删除</el-button>
            </div>

          </div>
        </el-card>
      </el-col>
    </el-row>
    <pagination v-show="total>0" :total="total" :page.sync="form.page" :limit.sync="form.limit" @pagination="getList" />

    <el-dialog
      :title="datasourceTitle"
      :visible.sync="datasourceDlgShow"
      v-if="datasourceDlgShow"
      width="39%"
    >
      <el-form
        ref="datasourceForm"
        :model="datasourceFormData"
        :rules="datasourceRule"
        label-width="120px"
        class="dialogClass"
      >
        <el-form-item label="数据库类型">
          <el-select
            v-model="datasourceFormData.dbType"
            filterable
            default-first-option
            :disabled="isDisabled"
            class="elSelect"
          >
            <el-option
              v-for="item in dbTypeConfig"
              :key="item.dbType"
              :label="item.label"
              :value="item.dbType"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="Host" prop="host">
          <el-input v-model.trim="datasourceFormData.host" placeholder="地址" show-word-limit maxlength="100" :disabled="isDisabled" />
        </el-form-item>
        <el-form-item label="Port" prop="port">
          <el-input v-model.trim="datasourceFormData.port" placeholder="端口" show-word-limit maxlength="10" :disabled="isDisabled" />
        </el-form-item>
        <el-form-item label="数据库" prop="dbName">
          <!-- <el-input v-model="datasourceFormData.dbName" :placeholder="dbNamePlaceholder" show-word-limit maxlength="64" /> -->
          <el-select
            v-model="datasourceFormData.dbName"
            filterable
            default-first-option
            placeholder="数据库"
            @focus="handleFocus"
            :disabled="isDisabled"
            class="elSelect"
          >
            <el-option
              v-for="item in dbTypelists"
              :key="item.dbType"
              :label="item.label"
              :value="item.dbType"
            />
          </el-select>
          <el-button type="primary" @click.stop="handleAdd" v-show="!isDisabled" style="margin-left: 10px;">新增数据库</el-button>
        </el-form-item>
        <!-- <el-form-item v-show="showOracleFields" label="连接类型">
          <el-select v-model="datasourceFormData.oracleConnType" :disabled="isDisabled">
            <el-option
              v-for="item in oracleConnTypeList"
              :key="item.val"
              :label="item.lab"
              :value="item.val"
            />
          </el-select>
        </el-form-item> 
        <el-form-item v-show="showPgSqlSchema" :label="schemaPlaceholder" :prop="schemaPlaceholder">
          <el-input v-model="datasourceFormData.schemaName" :placeholder="schemaPlaceholder+',如SCOTT'" show-word-limit maxlength="64" :disabled="isDisabled" />
        </el-form-item>-->
        <el-form-item label="Username" prop="username">
          <el-input v-model.trim="datasourceFormData.username" placeholder="用户名" show-word-limit maxlength="100" :disabled="isDisabled" />
        </el-form-item>
        <!-- <el-form-item v-show="showOracleFields" label="角色">
          <el-select v-model="datasourceFormData.oracleRole" clearable :disabled="isDisabled">
            <el-option
              v-for="item in oracleRoleList"
              :key="item.val"
              :label="item.lab"
              :value="item.val"
            />
          </el-select>
        </el-form-item> -->
        <el-form-item label="Password" prop="password">
          <el-input v-model.trim="datasourceFormData.password" type="password" placeholder="密码" show-word-limit maxlength="100" :disabled="isDisabled" />
        </el-form-item>
        <el-form-item label="数据库别名" prop="dbDesc">
          <el-input v-model="datasourceFormData.dbDesc" placeholder="数据库别名" show-word-limit maxlength="15" :disabled="isDisabled" />
        </el-form-item>
        <el-form-item v-show="!isDisabled">
          <el-button type="success" @click="onDatasourceTest">测试连接</el-button>
          <el-button type="primary" @click="onDatasourceSave">保存</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <el-dialog v-if="dialogdbVisible" :visible.sync="dialogdbVisible" width="30%" title="新增数据库">
      <el-form
        ref="dataDBForm"
        :rules="rules"
        :model="dbform"
        label-position="left"
        label-width="110px"
      >
        <el-form-item label="数据库名称" prop="dbName">
          <el-input v-model="dbform.dbName" placeholder="" clearable />
        </el-form-item>
        <el-form-item label="数据库字符集">
          <el-select v-model="dbform.characterType" placeholder="">
            <el-option v-for="item in importanceOptions" :key="item.code" :label="item.name" :value="item.code" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogdbVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="handleDB">
          确定
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { datasourcefindPage, projectSSave, projectsupdate, datasourcedbtype,datasourcecreateDb,datasourceconfigdbList,datasourceconfigtest,datasourceconfigupdate,datasourconfigcesave,datasourceconfigdelete } from '@/api/article'
import { getUserList } from '@/api/permission'
import waves from '@/directive/waves' // waves directive
import { parseTime } from '@/utils'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination 分页组件
import { mount } from '@vue/test-utils'
const current_datasource_id_key = 'gen-datasource-id'
const DB_TYPE = {
  MySQL: 1,
  Oracle: 2,
  SQL_Server: 3,
  PostgreSQL: 4,
  Dm: 5
}
export default {
  name: 'Database',
  components: { Pagination },
  directives: { waves }, // 指令

  data() {
    return {
      dbform:{
        dbName:"",
        characterType:"utf8"
      },
      rules:{
          dbName: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        // characterType: [
        //   { required: true, message: '不能为空', trigger: 'change' }
        // ],
      },
      dialogdbVisible:false,
      groupData: [],
      isDisabled: false,
      form: {
        dbName: '',
        page: 1,
        limit: 20
      },
      list: [], // 表格数据
      total: 0, // 总条数
      listLoading: true, // 表格加载数据时的 loading
      importanceOptions: [
        {
          code: "utf8",
          name: "utf8"
        },
        {
          code: "utf8mb4",
          name: "utf8mb4"
        }
      ],
      templateLists: [],
      datasourceTitle: '新建连接',
      datasourceDlgShow: false,
      datasourceFormData: {
        id: 0,
        dbType: 1,
        dbDesc: '',
        host: '',
        port: '',
        username: '',
        password: '',
        dbName: '',
        oracleConnType: '',
        oracleRole: '',
        schemaName: ''
      },
      datasourceRule: {
        host: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        port: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        username: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        dbName: [
          { required: true, message: '不能为空', trigger: 'change' }
        ]
      },
      dbTypeConfig: [],
      oracleConnTypeList: [{
        lab: '服务名',
        val: 1
      }, {
        lab: 'SID',
        val: 2
      }],
      oracleRoleList: [{
        lab: 'default',
        val: ''
      }, {
        lab: 'SYSDBA',
        val: 1
      }, {
        lab: 'SYSOPER',
        val: 2
      }],
      dbTypelists:[]
    }
  },
  computed: {
    showPgSqlSchema() {
      return this.datasourceFormData.dbType === DB_TYPE.PostgreSQL || this.datasourceFormData.dbType === DB_TYPE.Oracle
    },
    dbNamePlaceholder() {
      if (this.datasourceFormData.dbType === DB_TYPE.Oracle) {
        return '服务名'
      } else {
        return '数据库'
      }
    },
    schemaPlaceholder() {
      if (this.datasourceFormData.dbType === DB_TYPE.Oracle) {
        return '数据库'
      } else {
        return 'schema'
      }
    },
    showOracleFields() {
      return this.datasourceFormData.dbType === DB_TYPE.Oracle
    }
  },
  async mounted() {
    await this.datasourcedbtype()
    await this.getUserList()
    this.getList()
    
  },
  methods: {
    handleFocus(){
      if(!(this.datasourceFormData.host&&this.datasourceFormData.port&&this.datasourceFormData.username&&this.datasourceFormData.password)){
          this.$message({
            message: 'Host,port,username,password是必填项',
            type: 'error',
            showClose: true,
          })
          return
       }
      this.datasourceconfigdbList()
    },
    // 获取表格数据
    getList() {
      datasourcefindPage(this.form).then(response => {
        this.list = response.data.list
        console.log(this.templateLists,this.dbTypeConfig,6000)
        this.list.forEach(item => {
          if (item.adminId) {
            const obj = this.templateLists.find(v => v.userId === item.adminId)
            this.$set(item, 'admin_Name', obj ? obj.username : '')
          }
          if (item.dbType) {
            const obj = this.dbTypeConfig.find(v => v.dbType === item.dbType)
            this.$set(item, 'dbTypeName', obj ? obj.label : '')
          }
          if(item.createTime){
            item.create_Time=parseTime(item.createTime)
          }
        })
        this.total = response.data.totalCount
      })
    },
    async getUserList() {
      const res = await getUserList()
      if (res) {
        this.templateLists = res.data
      } else {
        this.templateLists = []
      }
    },
    async datasourcedbtype() {
      const res = await datasourcedbtype()
      if (res) {
        this.dbTypeConfig = res.data
      } else {
        this.dbTypeConfig = []
      }
    },
    async datasourceconfigdbList() {
      const res = await datasourceconfigdbList({
        dbType:1,
        host:this.datasourceFormData.host,
        port:this.datasourceFormData.port,
        username:this.datasourceFormData.username,
        password:this.datasourceFormData.password,
      })
      if (res) {
        this.dbTypelists = res.data.map(item=>{
          return {
            dbType:item,
            label:item
          }
        })
      } else {
        this.dbTypelists = []
      }
    },
   
    // 重新获取表格数据 页码归为1
    handleFilter() {
      this.form.page = 1
      this.getList()
    },
    handleReset() {
      this.form = {
        dbName: '',
        page: 1,
        limit: 20
      }
      this.getList()
    },
    onDataSourceAdd() {
      this.isDisabled = false
      this.datasourceTitle = '新建连接'
      this.datasourceDlgShow = true
      this.datasourceFormData={
        id: 0,
        dbType: 1,
        dbDesc: '',
        host: '',
        port: '',
        username: '',
        password: '',
        dbName: '',
        oracleConnType: '',
        oracleRole: '',
        schemaName: ''
      }
      this.dbTypelists=[]
    },
     handleLook(item) {
      this.isDisabled = true
      this.datasourceDlgShow = true
      this.datasourceTitle = '查看连接'
      this.datasourceFormData = JSON.parse(JSON.stringify(item))
    },
    handleEdit(item) {
      this.isDisabled = false
      this.datasourceDlgShow = true
      this.datasourceTitle = '编辑连接'
      this.datasourceFormData = JSON.parse(JSON.stringify(item))
    },
    handleCopy(item) {
      this.isDisabled = false
      this.datasourceDlgShow = true
      this.datasourceTitle = '复制连接'
      this.datasourceFormData = JSON.parse(JSON.stringify(item))
    },
    async handleDelete(item) {
      this.$confirm(`确定要进行删除操作?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        const res = await datasourceconfigdelete(item.id)
        if (res?.code===200) {
          this.$message({
            message: '删除成功',
            type: 'success'
          })
          this.getList()
        }
      })
    },
    handleAdd() {
       if(!(this.datasourceFormData.host&&this.datasourceFormData.port&&this.datasourceFormData.username&&this.datasourceFormData.password)){
          this.$message({
            message: 'Host,port,username,password是必填项',
            type: 'error'
          })
          return
       }
       this.dbform={
        dbName:"",
        characterType:"utf8"
       }
       this.dialogdbVisible=true
    },
    handleDB() {
       this.$refs.dataDBForm.validate(async (valid) => {
           if (valid) {
               this.dbform.dbType=this.datasourceFormData.dbType
               this.dbform.host=this.datasourceFormData.host
               this.dbform.port=this.datasourceFormData.port
               this.dbform.username=this.datasourceFormData.username
               this.dbform.password=this.datasourceFormData.password
               const res= await datasourcecreateDb(this.dbform)
               if(res?.code===200){
                   this.$message({
                    message: '创建成功',
                    type: 'success'
                  })
                  this.datasourceFormData.dbName=this.dbform.dbName
                  this.dialogdbVisible=false
               }
           }
       })
    },
    packageOracleFields() {
      // 处理oracle连接数据
      if (this.datasourceFormData.dbType === DB_TYPE.Oracle) {
        // 处理连接类型
        if (this.datasourceFormData.oracleConnType == 1) {
          this.datasourceFormData.dbName = '/' + this.datasourceFormData.dbName
        } else if (this.datasourceFormData.oracleConnType == 2) {
          this.datasourceFormData.dbName = ':' + this.datasourceFormData.dbName
        }
        // 处理账号角色
        if (this.datasourceFormData.oracleRole == 1) {
          this.datasourceFormData.username += ' AS SYSDBA'
        } else if (this.datasourceFormData.oracleRole == 2) {
          this.datasourceFormData.username += ' AS SYSOPER'
        }
      }
    },
    unPackOracleFields(item) {
      // 处理oracle属性 拆包
      if (item.dbType === DB_TYPE.Oracle) {
        // 处理连接类型
        if (item.dbName.startsWith("/")) {
          item.oracleConnType = 1;
          item.dbName = item.dbName.replace("/","");
        } else if (item.dbName.startsWith(":")) {
          item.oracleConnType = 2;
          item.dbName = item.dbName.replace(":","");
        }
        // 处理账号角色
        if (item.username.includes("AS SYSDBA")) {
          item.oracleRole = 1;
          item.username = item.username.replace(" AS SYSDBA", "");
        } else if (item.username.includes("AS SYSOPER")) {
          item.oracleRole = 2;
          item.username = item.username.replace(" AS SYSOPER", "");
        }
      }
    },
    onDatasourceTest() {
      // this.packageOracleFields()
      this.$refs.datasourceForm.validate(async (valid) => {
        if (valid) {
              const res =await datasourceconfigtest(this.datasourceFormData)
              if(res?.code===200){
                if (this.datasourceFormData.dbType === DB_TYPE.Oracle) {
                  // 处理连接类型
                  if (this.datasourceFormData.oracleConnType == 1) {
                    this.datasourceFormData.dbName = this.datasourceFormData.dbName.replace('/', '')
                  } else if (this.datasourceFormData.oracleConnType == 2) {
                    this.datasourceFormData.dbName = this.datasourceFormData.dbName.replace(':', '')
                  }
                  // 处理账号角色
                  if (this.datasourceFormData.oracleRole == 1) {
                    this.datasourceFormData.username = this.datasourceFormData.username.replace(' AS SYSDBA', '')
                  } else {
                    this.datasourceFormData.username = this.datasourceFormData.username.replace(' AS SYSOPER', '')
                  }
                }
                this.$message({
                    message: "测试连接成功",
                    type: 'success'
                })
              }
        }
      })
    },
    onDatasourceSave() {
      // this.packageOracleFields()
      this.$refs.datasourceForm.validate(async (valid) => {
        if (valid) {
            if (this.datasourceTitle == '编辑连接') {
              const res1 =await datasourceconfigupdate(this.datasourceFormData)
              if(res1?.code===200){
                this.$message({
                  message: '修改成功',
                  type: 'success'
                })
                this.datasourceDlgShow = false
                this.getList()
              }   
            }else{
               const res2 =await datasourconfigcesave(this.datasourceFormData)
                if(res2?.code===200){
                  this.$message({
                    message: '新增成功',
                    type: 'success'
                  })
                  this.datasourceDlgShow = false
                  this.getList()
                }
            }
        }
      })
    },
    getCurrentDataSourceId() {
      const id = this.getAttr(current_datasource_id_key)
      return parseInt(id) || ''
    },
    getDatasourceGroupMap(list) {
      const groups = {}
      for (const item of list) {
        let groupName = item.dbGroupName || '';
        groups[groupName] = groups[groupName] || []
        groups[groupName].push(item)
      }
      this.datasourceGroupMap = groups
    },
    loadDataSource() {
      const cacheId = this.getCurrentDataSourceId()
      this.post('/datasource/list', {}, resp => {
        let id
        const list = resp.data
        this.getDatasourceGroupMap(list)
        this.datasourceConfigList = list
        for (const item of list) {
          // 缓存id是否有效
          if (item.id === cacheId) {
            id = item.id
            break
          }
        }
        if (!id && list.length > 0) {
          id = list[0].id
        }
        if (id) {
          this.onDataSourceChange(parseInt(id))
        }
      })
    },
    
  }
}
</script>
<style lang="scss" scoped>
//表格布局的注释：
//$rowLength 这个变量表示了 筛选的搜索框会有多少行，由于在不同宽度显示器下 所占行数会不一定 ，所以下面使用媒体查询 做兼容
//最小兼容至 1366
@import '~@/styles/layout-table.scss';
$rowLength: 2;
@media all and (min-width: 1659px) {
    $rowLength: 2;
    @include calculation($rowLength: $rowLength);
}
@media all and (max-width: 1659px) {
    $rowLength: 3;
    @include calculation($rowLength: $rowLength);
}
.dialogClass .el-input,.elSelect{ 
  width: 450px;
}

</style>
